<?php
declare (strict_types=1);

namespace app\common\tool;

use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\GuzzleException;

class ApiClient
{
    /**
     * 基础路径
     * @var string
     */
    protected $baseUrl = '';
    /**
     * 当前客户端
     * @var \GuzzleHttp\Client
     */
    protected $client;

    public function __construct($baseUrl = '')
    {
        if (!empty($baseUrl)) {
            $this->baseUrl = $baseUrl;
        }
        $this->client = new \GuzzleHttp\Client([
            'base_uri' => $this->baseUrl,
            'timeout' => 10,
            'verify' => false,
        ]);
    }

    /**
     * 创建客户端
     * @param string $baseUrl
     * @return $this
     */
    public static function create($baseUrl = '')
    {
        return new static($baseUrl);
    }

    public function request(string $method, string $url, array $options = [], array $headers = []): Response
    {
        try {
            $options = $this->formOptions($options);
            if ($headers) {
                if (isset($options['headers'])) {
                    $options['headers'] = array_merge($options['headers'], $headers);
                } else {
                    $options['headers'] = $headers;
                }
            }

            return new Response($this->client->request($method, ltrim($url, '/'), $options));
        } catch (ClientException|GuzzleException $e) {
            return new Response($e->getResponse());
        }
    }

    /**
     * 生成表单配置选项
     * @param array $opts
     * @return array
     */
    protected function formOptions(array $opts): array
    {
        // 表单提交
        if (isset($opts['post'])) {
            $opts['form_params'] = $opts['post'];
            unset($opts['post']);
        }

        if (isset($opts['get'])) {
            $opts['query'] = $opts['get'];
            unset($opts['get']);
        }

        return $opts;
    }

    /**
     * put方法
     * @param string $url 请求地址
     * @param array $data 请求数据
     */
    public function put(string $url = '', array $data = [], array $headers = []): Response
    {
        return $this->request('PUT', $url, $data, $headers);
    }

    /**
     * post方法
     * @param string $url 请求地址
     * @param array $data 请求数据
     */
    public function post(string $url = '', array $data = [], array $headers = []): Response
    {
        return $this->request('POST', $url, $data, $headers);
    }

    /**
     * get方法
     * @param string $url 请求地址
     * @param array $data 请求数据
     */
    public function get(string $url = '', array $data = [], array $headers = []): Response
    {
        return $this->request('GET', $url, $data, $headers);
    }
}